package com.dave.getaway.app.service;

import com.dave.getaway.app.common.util.Constants;
import com.dave.getaway.app.common.util.ConvertUtil;
import com.dave.getaway.app.model.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wangwj
 * @version 1.0
 * @date 2021/12/16
 * @description: TODO
 */

@Slf4j
@Component
public class GetaWayGenericService {

    private final Map<String, GenericService> currentDubboService = new ConcurrentHashMap(16);
    @Autowired
    private ProviderService providerService;

    public String sayHello(String text) {
        GenericService genericService = currentDubboService.get("com.dave.dubbo.provider.api.MessageService_2_7_8:1.0.0");

        if (genericService == null) {
            List<Provider> providers = providerService.getServiceDTOS();
            providers.stream().forEach(x -> this.initReferenceConfig(x));
            log.info("加载泛化服务完成");
        }

        // 基本类型以及Date,List,Map等不需要转换，直接调用
        Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{text});
        return result.toString();
    }

    public String sayHello2(String name) {
        GenericService genericService = currentDubboService.get("com.dave.dubbo.provider.api.MessageService_2_7_8:1.0.0");

        if (genericService == null) {
            List<Provider> providers = providerService.getServiceDTOS();
            providers.stream().forEach(x -> this.initReferenceConfig(x));
            log.info("加载泛化服务完成");
        }

        Map<String, Object> person = new HashMap<String, Object>();
        person.put("id", "1");
        person.put("name", name);
        Object result = genericService.$invoke("sayHelloUser", new String[]{"com.dave.dubbo.provider.api.entity.UserTest"}, new Object[]{person});
        return result.toString();
    }


    private void initReferenceConfig(Provider provider) {
        Map<String, String> info = ConvertUtil.serviceName2Map(provider.getServiceName());
        // 引用远程服务
        // 该实例很重量，里面封装了所有与注册中心及服务提供方连接，请缓存
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        // 弱类型接口名
        reference.setInterface(info.get(Constants.INTERFACE_KEY));
        reference.setVersion(info.get(Constants.VERSION_KEY));
        // 声明为泛化接口
        reference.setGeneric(true);

        // 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用
        GenericService genericService = reference.get();

        currentDubboService.put(provider.getServiceName(), genericService);
    }


}
